package fun.codedesign.yinxue.util;

import java.lang.reflect.Field;
import java.math.BigInteger;
import java.util.Iterator;
import java.util.List;

import fun.codedesign.yinxue.util.map.TwoValueMap;

/**
 * 组装SQL语句的工具类 <br>
 *
 * @author zengjian
 * @create 2018-06-07 12:00
 * @since 1.0.0
 */
public final class SQLUtil {

    private SQLUtil() {
    }

    public static final int LENGTH = 1 << 8;

    /**
     * 从url地址中截取获得连接数据库名称<br>
     * <pre>
     *     url示例：jdbc:mysql://127.0.0.1:3306/family?useAffectedRows=true&useSSL=true
     *     截取规则：从最后 "/"开始截取，如果有"?"截取到"?"; 如果没有截取到末尾
     * </pre>
     *
     * @param url 数据库连接url
     * @return databaseName 数据库名称
     */
    public static String getDatabaseName(String url) {
        String databaseName = null;
        if (url.contains("?")) {
            databaseName = url.substring(url.lastIndexOf("/") + 1, url.lastIndexOf("?"));
        } else {
            databaseName = url.substring(url.lastIndexOf("/") + 1);
        }
        return databaseName;
    }

    public static <T> String buildCreateTableSql(T t, String tableName) {
        // 默认采用ID作为自增ID
        final String primaryType = " `ID` bigint(10) NOT NULL AUTO_INCREMENT,\n";
        final String defaultType = " varchar(100) DEFAULT NULL\n";
        final String footer = ") ENGINE=InnoDB DEFAULT CHARSET=utf8;";
        List<Field> fields = ReflectUtil.getFields(t);
        Iterator<Field> iterator = fields.iterator();
        StringBuilder sqlBuilder = new StringBuilder(LENGTH);
        sqlBuilder.append("CREATE TABLE `").append(tableName).append("`(\n").append(primaryType);
        while (iterator.hasNext()){
            String fieldName = iterator.next().getName();
            if ("id".equalsIgnoreCase(fieldName)){
                continue;
            }
            sqlBuilder.append(addQuotationMark(fieldName)).append(defaultType);
            if (iterator.hasNext()){
                sqlBuilder.append(",");
            }
        }
        sqlBuilder.append(", PRIMARY KEY (").append("`ID`").append(")")
                .append(footer);
        return sqlBuilder.toString();
    }

    private static String addQuotationMark(String text) {
        return "`" + text + "`";
    }

    public static String buildSelectSql(String tableName) {
        StringBuilder sb = new StringBuilder(LENGTH);
        sb.append("select * from ").append(tableName);
        return sb.toString();
    }

    public static String toBuildSelectCountSql(String tableName) {
        StringBuilder sb = new StringBuilder(LENGTH);
        sb.append("select count(*) from ").append(tableName);
        return sb.toString();
    }

    public static <T> String toBuildUpdateSql(T t, String tableName, TwoValueMap keyValueTwo) throws NoSuchFieldException, IllegalAccessException {
        int paramSize = keyValueTwo.size();
        StringBuilder sb = new StringBuilder(LENGTH);
        sb.append("update ").append(tableName).append(" set ");
        for (int i = 0; i < paramSize; i++) {
            sb.append(keyValueTwo.get(i).getValue1()).append("=?,");
        }
        sb.setCharAt(sb.lastIndexOf(","), ' ');
        sb.append("where id=").append(ReflectUtil.getFieldValue(t, "id"));
        return sb.toString();
    }

    public static <T> String toBuildDeleteSql(String tableName, BigInteger id) {
        StringBuilder sb = new StringBuilder(LENGTH);
        if (id != null) {
            sb.append("delete from '").append(tableName).append("'where id = ?");
        } else {
            sb.append("delete from ").append(tableName);
        }
        return sb.toString();
    }

    public static String buildInsertSql(String tableName, int placeHolderCount) {
        StringBuilder sb = new StringBuilder(LENGTH);
        sb.append("insert into ").append(tableName).append(" values ").append("(");
        for (int i = 0; i < placeHolderCount; i++) {
            sb.append("?,");
        }
        sb.setCharAt(sb.lastIndexOf(","), ')');
        return sb.toString();
    }


}
